import time, string, random, asyncio, aiohttp, sqlite3, hashlib, json
import models, yygive

def myFibonacci(no, r=1):
    a = 8
    b = 3 * r
    if no == 0:
        return a * b
        try:
            for i in range(no):
                a, b = b, b + a

        except TypeError as e:
            print('')
            print(e)

        return b


def decipher(data, proof):
    lenp = len(proof)
    rs = ''
    for i in range(len(data)):
        a = int(proof[i % lenp])
        by = (data[i] + 256 - myFibonacci(a, a)) % 256
        rs += chr(by)

    return rs


yzm_dic = {}
yzm_timeout = 300
con = None




async def create_card_key(num, face_amount):
    symbols = [str(x) for x in range(0,10)]
    for p in yygive.present_list:
        if face_amount >= p.base_line:
            symbols = p.symbols
            break
    keys = []
    i = 0
    while(i < num):
        i += 1
        key = ('').join(random.sample(string.ascii_letters + string.digits, 17))
        key = ''.join(random.sample(symbols, 1)) + key
        try:
            card = models.PrepaidCard(card_key=key, amount = face_amount)
            await card.save()
            keys.append([key, face_amount])
        except sqlite3.IntegrityError as e:
            i -= 1
    return keys

async def check_card_key(key):
    res = await models.PrepaidCard.findAll(where = 'card_key = ? and status = ?', args = [key, 0])
    if not res:
        return None
    res[0].status = 1
    await res[0].update()
    return res[0].amount


async def test_send_yzm(phone):
    yzm = Yzm()
    res = await yzm.test_send_yzm(phone)
    yzm_dic[phone] = yzm
    return res


async def send_yzm(phone):
    
    yzm = Yzm()
    res = await yzm.send_yzm(phone)
    #yzm_dic[phone] = yzm
    #return res
    if res:
        yzm_dic[phone] = yzm
        return True
    return False

def check_yzm(phone, code):
    y = yzm_dic.get(phone)
    if y and y.code == code:
        yzm_dic.pop(phone)
        return True
    return False

async def monitor_yzm():
    await asyncio.sleep(1)
    while(True):
        n = int(time.time())
        for phone in yzm_dic.keys():
            if n - int(yzm_dic[phone].time) > yzm_timeout:
                yzm_dic.pop(phone)
        await asyncio.sleep(120)

class Yzm(object):
    '''
    验证码类
    '''
    url = 'http://yypt.51nche.com/voice/smscode/send.do'
    cusNo = 'C2019042210403171981'
    key = '296fd744f2ebbb84a354b55e4b29bde9'
    voiceTemplateId = 'VF2019042218114706012'

    def __init__(self):
        self.code = str(random.randint(100000,999999))
        self.time = str(int(time.time()))
        self.taskId = ('').join(random.sample(string.ascii_letters + string.digits, 12))

    async def test_send_yzm(self, phone):
        return self.code
    
    async def send_yzm(self, phone):
        md5Str = (Yzm.cusNo + phone + self.time + Yzm.key)
        md = hashlib.md5()
        md.update(md5Str.encode('utf-8'))
        sign = md.hexdigest()
        data = {'cusNo':Yzm.cusNo,'called':phone,'vfcode':','.join(self.code),'voiceTemplateId':Yzm.voiceTemplateId,'timestamp':self.time,'sign':sign,'taskId':self.taskId}
        async with con.post(Yzm.url, data = data) as resp:
            text = await resp.text()
            j = json.loads(text)
            if j['retcode'] == 0:
                return True
            print(text)
            return False